'''
GMM实例 聚类算法实例
k-means聚类算法和高斯混合模型聚类的比较:常规数据使用k-means和GMM聚类效果差不多，但是如果数据比较复杂的情况下，使用gmm模型一般聚类效果更好
尤其是当数据集服从高斯分布时
'''
import pandas as pd
from matplotlib import  pyplot as plt
from  sklearn.decomposition import PCA
from sklearn.mixture import GaussianMixture
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import KMeans
import numpy as np

def sinplot():
    data = pd.read_csv ('E:\培训教程\python\唐宇迪-机器学习课程\机器学习算法配套案例实战\GMM聚类\GMM聚类\Fremont.csv', index_col='Date', parse_dates=True)
    print(data.head())

    '''
    Visualizing the Dataset
    data.plot()
    数据重采样，按周进行计算
    '''
    #data.resample('w').sum().plot()

    '''对数据采用滑动窗口计算'''
    #(data.resample('D').sum().rolling(365).sum()).plot()
    #(data.resample('D').sum().rolling(365).sum()/365).plot()

    #data.groupby(data.index.time).mean().plot()
    plt.xticks(rotation=45)

    data.columns = ['West', 'East']
    data['Total'] = data['West'] + data['East']
    pivoted = data.pivot_table('Total', index=data.index.time, columns=data.index.date)
    X = pivoted.fillna(0).T.values

    '''
    使用PCA对数据进行降维，降到2维数据,数据降维之后，已经失去了原先的物理意义，但是空间意义还在
    '''
    X2 = PCA(2).fit_transform(X)
    print(X2)
    plt.scatter(X2[:, 0], X2[:, 1])


    '''使用GMM模型(高斯混合模型)对数据进行降维到2维度(其实就是隐变量的个数)，然后在对数据进行聚类并可视化展示'''
    gmm = GaussianMixture(2)
    gmm.fit(X)
    labels1 = gmm.predict_proba(X)  # 返回的是概率值
    labels = gmm.predict(X)         # 返回的是预测值
    plt.scatter(X2[:, 0], X2[:, 1], c=labels, cmap='rainbow')
    plt.show()

def sinplot1():
    '''
    展示k-means聚类算法和GMM聚类算法的区别
    随机创建数据点,并可视化
    '''
    X, y_true = make_blobs(n_samples=800, centers=4, random_state=11)
    #plt.scatter(X[:, 0], X[:, 1])
    #plt.show()


    '''
    当数据本身就比较好分得开的时候，使用k-means和gmm聚类得效果基本相同
    使用k-means对数据聚类
    '''
    kmeans = KMeans(n_clusters=4)
    kmeans.fit(X)
    y_kmeans = kmeans.predict(X)

    #plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')
    centers = kmeans.cluster_centers_
    print(centers)

    '''使用Gmm对数据进行聚类'''
    gmm = GaussianMixture(n_components=4).fit(X)
    labels = gmm.predict(X)
    #plt.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis')

    '''
    当数据集中包含有高斯分布，并且数据集比较不容易分开的时候，使用GMM聚类的效果比k-means效果会好很多
    因为GMM内部就是基于高斯分布计算的，而k-means是基于距离计算的
    '''
    rng = np.random.RandomState(13)
    X_stretched = np.dot(X, rng.randn(2, 2))

    kmeans = KMeans(n_clusters=4, random_state=1)
    kmeans.fit(X_stretched)
    y_kmeans = kmeans.predict(X_stretched)
    plt.scatter(X_stretched[:, 0], X_stretched[:, 1], c=y_kmeans, s=50, cmap='viridis')
    centers = kmeans.cluster_centers_
    print(centers)
    plt.show()


    gmm = GaussianMixture(n_components=4)
    gmm.fit(X_stretched)
    y_gmm = gmm.predict(X_stretched)
    plt.scatter(X_stretched[:, 0], X_stretched[:, 1], c=y_gmm, s=50, cmap='viridis')

    plt.show()
if __name__ == '__main__':
    sinplot1()